import numpy as np
import matplotlib.pyplot as plt

def cal_dis(line_point1, line_point2, point):
    A = line_point2[1] - line_point1[1]
    B = line_point1[0] - line_point2[0]
    C = (line_point1[1] - line_point2[1]) * line_point1[0] + \
        (line_point2[0] - line_point1[0]) * line_point1[1]
    distance1 = np.abs(A * point[0] + B * point[1] + C) / (np.sqrt(A ** 2 + B ** 2))
    X = point[0] - A * (A * point[0] + B * point[1] + C) / (A * A + B * B)
    Y = point[1] - B * (A * point[0] + B * point[1] + C) / (A * A + B * B)
    distance2 = np.sqrt((X - line_point1[0]) ** 2 + (Y - line_point1[1]) ** 2)

    if Y > point[1]:
        distance1 = -distance1

    return distance1, distance2


def translation(ordinates):
    ordinates_trans = np.empty_like(ordinates)
    line1_id = np.argmin(ordinates[:, 0])
    line2_id = np.argmax(ordinates[:, 0])

    while True:
        k, b = calK(ordinates[line1_id], ordinates[line2_id])
        flag = pointInOrOut(k, b, ordinates[line1_id - 1])
        if flag:
            break
        else:
            line1_id -= 1
    while True:
        k, b = calK(ordinates[line1_id], ordinates[line2_id])
        flag = pointInOrOut(k, b, ordinates[line1_id + 1])
        if flag:
            break
        else:
            line1_id += 1

    line1_point = ordinates[line1_id]
    line2_point = ordinates[line2_id]
    k, b = calK(line1_point, line2_point)

    for i, ordinate in enumerate(ordinates):
        dis1, dis2 = cal_dis(line1_point,
                             line2_point,
                             ordinate)
        ordinates_trans[i] = np.asarray([dis2, dis1])

    min = np.min(ordinates_trans[:, 0])
    max = np.max(ordinates_trans[:, 0])
    ordinates_trans[:, 0] = (ordinates_trans[:, 0] - min) / (max - min)

    return ordinates_trans


def calK(line_point1, line_point2):
    k = (line_point2[1] - line_point1[1]) / (line_point2[0] - line_point1[0])
    k = -1 / k
    b = -k * line_point1[0] + line_point1[1]
    return k, b


def pointInOrOut(k, b, point):
    return (k * point[0] + b - point[1]) > 0

